#include "placecirculararctool.h"
#include "item/circulararcitem.h"
#include "command/additemcommand.h"
#include "view/scene.h"

#include <QGraphicsSceneMouseEvent>
#include <QLineF>

namespace SymbolEditor
{

    PlaceCircularArcTool::PlaceCircularArcTool(QObject *parent):
        AbstractTool(parent),
        m_state(WaitingForActivation),
        m_item(nullptr)
    {
        setLabel("<b>P</b>lace a circular <b>A</b>rc");
        setShortcut(QKeySequence("p,a"));
        setIcon(QIcon::fromTheme("draw-halfcircle3"));
        updateAction();
    }

    PlaceCircularArcTool::~PlaceCircularArcTool()
    {
    }

    void PlaceCircularArcTool::addItem()
    {
        m_item = new GraphicsCircularArcItem();
        m_item->setEnabled(false);
        scene()->addItem(m_item);
    }

    void PlaceCircularArcTool::updateItem()
    {
        m_item->setProperty(PositionProperty, m_center);
        m_item->setProperty(RadiusProperty, QLineF(m_center, m_radiusPos).length());
        QLineF startLine(m_center, m_startAnglePos);
        m_item->setProperty(StartAngleProperty, startLine.angle());
        QLineF spanLine(m_center, m_spanAnglePos);
        m_item->setProperty(SpanAngleProperty, startLine.angleTo(spanLine));
    }

    void PlaceCircularArcTool::removeItem()
    {
        scene()->removeItem(m_item);
        delete m_item;
    }

    bool PlaceCircularArcTool::mouseClickEvent(QGraphicsSceneMouseEvent *event)
    {
        switch (m_state)
        {
            case WaitingForActivation:
                break;
            case WaitingForCenter:
            {
                m_center = m_radiusPos = m_startAnglePos = m_spanAnglePos = event->scenePos();
                addItem();
                updateItem();
                m_state = WaitingForRadius;
                break;
            }
            case WaitingForRadius:
            {
                m_radiusPos = m_startAnglePos = m_spanAnglePos = event->scenePos();
                updateItem();
                m_state = WaitingForStartAngle;
                break;
            }
            case WaitingForStartAngle:
            {
                m_startAnglePos = m_spanAnglePos = event->scenePos();
                updateItem();
                m_state = WaitingForSpanAngle;
                break;
            }
            case WaitingForSpanAngle:
            {
                m_spanAnglePos = event->scenePos();
                updateItem();
                m_item->setEnabled(true);

                auto command = new AddItemCommand();
                command->setItemType(CircularArc); // FIXME: typeForDocument()
                command->setItemProperties(m_item->properties());
                appendCommand(command);

                removeItem();
                m_state = WaitingForCenter;
                break;
            }
        }
        return true;
    }

    bool PlaceCircularArcTool::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        switch (m_state)
        {
            case WaitingForActivation:
                break;
            case WaitingForCenter:
                break;
            case WaitingForRadius:
                m_radiusPos = event->scenePos();
                updateItem();
                break;
            case WaitingForStartAngle:
                m_startAnglePos = event->scenePos();
                updateItem();
                break;
            case WaitingForSpanAngle:
                m_spanAnglePos = event->scenePos();
                updateItem();
                break;
        }
        return true;
    }

    void PlaceCircularArcTool::activate(Scene *scene)
    {
        if (m_state != WaitingForActivation)
        {
            desactivate();
        }
        setScene(scene);
        m_state = WaitingForCenter;
    }

    void PlaceCircularArcTool::desactivate()
    {
        switch (m_state)
        {
            case WaitingForActivation:
            case WaitingForCenter:
                break;
            case WaitingForRadius:
            case WaitingForStartAngle:
            case WaitingForSpanAngle:
                removeItem();
                break;
        }
        setScene(nullptr);
        m_state = WaitingForActivation;
    }

}
